package com.pj.utils;

import cn.hutool.json.JSONUtil;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.google.gson.Gson;
import com.pj.utils.cache.RedisUtil;
import com.pj.utils.sg.AjaxError;
import com.pj.utils.sg.IpCheckUtil;
import com.pj.utils.sg.NbUtil;
import com.pj.utils.sms.entity.SmsSetting;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;


/**
 * 封装一下手机验证码的相关逻辑 ，包括：验证，防重发，防ip频繁等等
 * @author kong
 *
 */
@Slf4j
public class VcUtil {

	private final static String smsString = "{\"accessKeyId\":\"LTAI5tBQs7GhW2ufsYqqd83y\",\"signName\":\"新农邦\",\"accessSecret\":\"P4ziAygi7J7OZ4mHKoRTuvoiqg33JC\",\"regionId\":\"SMS_239313126\"}";

	// --------------------- 对接短信登录，只需更改以下两个方法的代码即可 start --------------------- 
	
	/**
	 * 对接第三方平台发送验证码，发送成功返回true，失败返回false 
	 * @param phone 手机号
	 * @param vc 验证码 
	 * @return 是否成功发送 
	 */
	private static boolean sendVc(String phone, String vc,String smsString) {
		// ... 发送验证码

		SmsSetting smsSetting = new Gson().fromJson(smsString, SmsSetting.class);

		//准备发送短信参数
		Map<String, String> params = new HashMap<>(2);
		//验证码内容
		params.put("code", vc);

		com.aliyun.dysmsapi20170525.Client client = createClient();
		SendSmsRequest sendSmsRequest = new SendSmsRequest()
				.setSignName(smsSetting.getSignName())
				.setPhoneNumbers(phone)
				.setTemplateCode(smsSetting.getRegionId())
				.setTemplateParam(JSONUtil.toJsonStr(params));
		try {
			SendSmsResponse response = client.sendSms(sendSmsRequest);
		} catch (Exception e) {
			log.error("发送短信错误", e);
		}
		return true;
	}
	/**
	 * 初始化账号Client
	 *
	 * @return Client 短信操作util
	 */
	public static com.aliyun.dysmsapi20170525.Client createClient() {
		try {
			SmsSetting smsSetting = new Gson().fromJson(smsString, SmsSetting.class);

			Config config = new Config();
			//您的AccessKey ID
			config.accessKeyId = smsSetting.getAccessKeyId();
			//您的AccessKey Secret
			config.accessKeySecret = smsSetting.getAccessSecret();
			//访问的域名
			config.endpoint = "dysmsapi.aliyuncs.com";
			return new com.aliyun.dysmsapi20170525.Client(config);
		} catch (Exception e) {
			log.error("短信初始化错误", e);
		}
		return null;
	}
	
	/**
	 * 随机生成一个验证码 
	 * @return 验证码 
	 */
	private static String randomVc() {
//		return "123456";
		return NbUtil.getcolde();
	}
	
	// --------------------- end --------------------- 
	

	/**
	 * 验证码存活时长，单位分钟
	 */
	final static int ckc_time = 30;

	// 用不同 type 隔离不同业务
	public final static String USER_LOGIN = "VC_USER_LOGIN:";		// 用户登录 
	public final static String USER_UPDATE_PWD = "VC_USER_UPDATE_PWD:";		// 用户更改密码 
	
	
	/**
	 * 发送一个验证码 （号码有效性、防重复发送、防ip频繁）
	 * @param type 业务type 
	 * @param phone 手机号 
	 */
	public static void send(String type, String phone,String smsString) {
		// 先验证
		if(NbUtil.isPhone(phone) == false){
			throw new AjaxError("无效手机号码");
		}
		// 防重发
		if(RedisUtil.get(type + phone) != null){
			throw new AjaxError("该手机号验证码已发送，请注意查收");
		}
		// 校验ip是否频繁访问 
		IpCheckUtil.checkRes("user-login-send-vc", 30); 

		// 开始发送
		String number = randomVc();
		boolean bool = sendVc(phone, number,smsString);
		if(bool){
			// 存入redis 
			RedisUtil.setByMINUTES(type + phone, number, ckc_time);
			// 记录IP
			IpCheckUtil.setNow("user-login-send-vc");	
			return;
		}
		throw new AjaxError("验证码发送失败");
	}

	/**
	 * 校验一个手机号的验证码是否正确 
	 * @param type 业务类型 
	 * @param phone 手机号
	 * @param number 验证码 
	 */
	public static void check(String type, String phone, String number) {
		// 验证手机号
		if(NbUtil.isPhone(phone) == false) {
			throw new AjaxError("请输入一个正确的手机号码");
		}
		// 校验短信码
		String vc = RedisUtil.get(type + phone);
		if(vc == null){
			throw new AjaxError("验证码错误.");
		}
		if(vc.equals(number) == false) {
			throw new AjaxError("验证码错误");
		}
	}
	
	/**
	 * 删除指定手机号的验证码 
	 * @param type 业务类型 
	 * @param phone 手机号
	 */
	public static void delete(String type, String phone) {
		RedisUtil.del(type + phone);
	}

}
